package com.kexio.enterprise.governance.circuitbreaker;

import com.kexio.enterprise.governance.circuitbreaker.config.CircuitBreakerConfig;
import com.kexio.enterprise.governance.circuitbreaker.enums.CircuitBreakerState;
import com.kexio.enterprise.governance.circuitbreaker.listener.CircuitBreakerStateChangeListener;
import com.kexio.enterprise.governance.circuitbreaker.result.CircuitBreakerResult;
import com.kexio.enterprise.governance.circuitbreaker.statistics.CircuitBreakerStatistics;
import com.kexio.enterprise.governance.circuitbreaker.status.CircuitBreakerStatus;

import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier;

/**
 * 熔断器服务接口
 * 
 * 提供服务熔断、降级和恢复功能
 * 
 * @author Kexio
 * @since 1.0.0
 */
public interface CircuitBreakerService {

    /**
     * 执行受保护的操作
     * 
     * @param key      熔断器键
     * @param supplier 操作提供者
     * @param <T>      返回类型
     * @return 执行结果
     */
    <T> CircuitBreakerResult<T> execute(String key, Supplier<T> supplier);

    /**
     * 执行受保护的操作（带降级）
     * 
     * @param key      熔断器键
     * @param supplier 操作提供者
     * @param fallback 降级操作
     * @param <T>      返回类型
     * @return 执行结果
     */
    <T> CircuitBreakerResult<T> execute(String key, Supplier<T> supplier, Supplier<T> fallback);

    /**
     * 执行受保护的操作（自定义配置）
     * 
     * @param key      熔断器键
     * @param supplier 操作提供者
     * @param config   熔断器配置
     * @param <T>      返回类型
     * @return 执行结果
     */
    <T> CircuitBreakerResult<T> execute(String key, Supplier<T> supplier, CircuitBreakerConfig config);

    /**
     * 异步执行受保护的操作
     * 
     * @param key      熔断器键
     * @param supplier 操作提供者
     * @param <T>      返回类型
     * @return 异步执行结果
     */
    <T> CompletableFuture<CircuitBreakerResult<T>> executeAsync(String key, Supplier<T> supplier);

    /**
     * 异步执行受保护的操作（带降级）
     * 
     * @param key      熔断器键
     * @param supplier 操作提供者
     * @param fallback 降级操作
     * @param <T>      返回类型
     * @return 异步执行结果
     */
    <T> CompletableFuture<CircuitBreakerResult<T>> executeAsync(String key, Supplier<T> supplier, Supplier<T> fallback);

    /**
     * 检查熔断器是否允许执行
     * 
     * @param key 熔断器键
     * @return 是否允许
     */
    boolean isExecutionAllowed(String key);

    /**
     * 记录成功执行
     * 
     * @param key          熔断器键
     * @param executionTime 执行时间（毫秒）
     */
    void recordSuccess(String key, long executionTime);

    /**
     * 记录失败执行
     * 
     * @param key       熔断器键
     * @param exception 异常
     */
    void recordFailure(String key, Throwable exception);

    /**
     * 记录超时
     * 
     * @param key 熔断器键
     */
    void recordTimeout(String key);

    /**
     * 手动打开熔断器
     * 
     * @param key 熔断器键
     */
    void forceOpen(String key);

    /**
     * 手动关闭熔断器
     * 
     * @param key 熔断器键
     */
    void forceClose(String key);

    /**
     * 重置熔断器
     * 
     * @param key 熔断器键
     */
    void reset(String key);

    /**
     * 获取熔断器状态
     * 
     * @param key 熔断器键
     * @return 熔断器状态
     */
    CircuitBreakerState getState(String key);

    /**
     * 获取熔断器详细状态
     * 
     * @param key 熔断器键
     * @return 详细状态
     */
    CircuitBreakerStatus getStatus(String key);

    /**
     * 设置熔断器配置
     * 
     * @param key    熔断器键
     * @param config 配置
     */
    void setConfig(String key, CircuitBreakerConfig config);

    /**
     * 获取熔断器配置
     * 
     * @param key 熔断器键
     * @return 配置
     */
    CircuitBreakerConfig getConfig(String key);

    /**
     * 删除熔断器
     * 
     * @param key 熔断器键
     */
    void remove(String key);

    /**
     * 获取所有熔断器键
     * 
     * @return 熔断器键集合
     */
    java.util.Set<String> getAllKeys();

    /**
     * 获取熔断器统计信息
     * 
     * @param key 熔断器键
     * @return 统计信息
     */
    CircuitBreakerStatistics getStatistics(String key);

    /**
     * 获取所有熔断器统计信息
     * 
     * @return 统计信息映射
     */
    Map<String, CircuitBreakerStatistics> getAllStatistics();

    /**
     * 清空统计信息
     * 
     * @param key 熔断器键
     */
    void clearStatistics(String key);

    /**
     * 添加状态变化监听器
     * 
     * @param key      熔断器键
     * @param listener 监听器
     */
    void addStateChangeListener(String key, CircuitBreakerStateChangeListener listener);

    /**
     * 移除状态变化监听器
     * 
     * @param key      熔断器键
     * @param listener 监听器
     */
    void removeStateChangeListener(String key, CircuitBreakerStateChangeListener listener);

    /**
     * 检查熔断器是否存在
     * 
     * @param key 熔断器键
     * @return 是否存在
     */
    boolean exists(String key);
}